"""
文件管理模块

提供文件读写和路径验证功能。
"""

import os
from pathlib import Path
from typing import Optional


class FileManager:
    """文件管理类"""
    
    def __init__(self) -> None:
        self.supported_extensions = {
            '.py', '.js', '.ts', '.jsx', '.tsx', '.java', '.cpp', '.c', '.h',
            '.cs', '.php', '.rb', '.go', '.rs', '.swift', '.kt', '.scala',
            '.html', '.css', '.scss', '.sass', '.xml', '.json', '.yaml', '.yml',
            '.toml', '.ini', '.cfg', '.conf', '.md', '.txt', '.sql', '.sh',
            '.bat', '.ps1', '.dockerfile', '.gitignore', '.env'
        }
    
    def read_file(self, file_path: str) -> str:
        """
        读取文件内容
        
        Args:
            file_path: 文件路径
            
        Returns:
            文件内容
            
        Raises:
            FileNotFoundError: 文件不存在
            PermissionError: 没有读取权限
            UnicodeDecodeError: 编码错误
        """
        path = Path(file_path)
        
        # 检查文件是否存在
        if not path.exists():
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        # 检查是否为文件
        if not path.is_file():
            raise ValueError(f"路径不是文件: {file_path}")
        
        # 检查文件大小（限制为10MB）
        if path.stat().st_size > 10 * 1024 * 1024:
            raise ValueError(f"文件过大: {file_path} (超过10MB)")
        
        # 检查文件扩展名
        if path.suffix.lower() not in self.supported_extensions:
            raise ValueError(f"不支持的文件类型: {path.suffix}")
        
        try:
            # 尝试UTF-8编码
            with open(path, 'r', encoding='utf-8') as f:
                return f.read()
        except UnicodeDecodeError:
            # 如果UTF-8失败，尝试其他编码
            try:
                with open(path, 'r', encoding='gbk') as f:
                    return f.read()
            except UnicodeDecodeError:
                raise UnicodeDecodeError(f"无法解码文件: {file_path}")
    
    def write_file(self, file_path: str, content: str, overwrite: bool = False) -> None:
        """
        写入文件内容
        
        Args:
            file_path: 文件路径
            content: 要写入的内容
            overwrite: 是否覆盖现有文件
            
        Raises:
            FileExistsError: 文件已存在且不允许覆盖
            PermissionError: 没有写入权限
        """
        path = Path(file_path)
        
        # 检查文件是否已存在
        if path.exists() and not overwrite:
            raise FileExistsError(f"文件已存在: {file_path}")
        
        # 确保目录存在
        path.parent.mkdir(parents=True, exist_ok=True)
        
        try:
            with open(path, 'w', encoding='utf-8') as f:
                f.write(content)
        except Exception as e:
            raise RuntimeError(f"写入文件失败: {e}")
    
    def append_file(self, file_path: str, content: str) -> None:
        """
        追加内容到文件
        
        Args:
            file_path: 文件路径
            content: 要追加的内容
        """
        path = Path(file_path)
        
        # 确保目录存在
        path.parent.mkdir(parents=True, exist_ok=True)
        
        try:
            with open(path, 'a', encoding='utf-8') as f:
                f.write(content)
        except Exception as e:
            raise RuntimeError(f"追加文件失败: {e}")
    
    def file_exists(self, file_path: str) -> bool:
        """
        检查文件是否存在
        
        Args:
            file_path: 文件路径
            
        Returns:
            文件是否存在
        """
        return Path(file_path).exists()
    
    def is_file(self, file_path: str) -> bool:
        """
        检查路径是否为文件
        
        Args:
            file_path: 文件路径
            
        Returns:
            是否为文件
        """
        path = Path(file_path)
        return path.exists() and path.is_file()
    
    def get_file_size(self, file_path: str) -> int:
        """
        获取文件大小
        
        Args:
            file_path: 文件路径
            
        Returns:
            文件大小（字节）
        """
        return Path(file_path).stat().st_size
    
    def get_file_extension(self, file_path: str) -> str:
        """
        获取文件扩展名
        
        Args:
            file_path: 文件路径
            
        Returns:
            文件扩展名
        """
        return Path(file_path).suffix.lower()
    
    def is_supported_file(self, file_path: str) -> bool:
        """
        检查是否为支持的文件类型
        
        Args:
            file_path: 文件路径
            
        Returns:
            是否为支持的文件类型
        """
        return self.get_file_extension(file_path) in self.supported_extensions
    
    def list_files(self, directory: str, pattern: str = "*") -> list:
        """
        列出目录中的文件
        
        Args:
            directory: 目录路径
            pattern: 文件匹配模式
            
        Returns:
            文件列表
        """
        path = Path(directory)
        if not path.exists() or not path.is_dir():
            return []
        
        files = []
        for file_path in path.glob(pattern):
            if file_path.is_file() and self.is_supported_file(str(file_path)):
                files.append(str(file_path))
        
        return sorted(files)
